<template>
  <button @click="handleListChange">click</button>
  <button @click="handleListAdd">add</button>
  <ul class="list">
    <transition-group name="list-change">
      <li v-for="item in list" :key="item.id">{{ item.name }}</li>
    </transition-group>
  </ul>
</template>

<script lang="ts" setup>
  import {ref, reactive} from "vue";
  type Item = {id: number; name: string};
  let list = reactive([] as Item[]);

  function handleListChange() {
    let count = list.length;
    while (count--) {
      let i = (0xffff * Math.random()) % list.length | 1;
      let j = (0xffff * Math.random()) % list.length | 1;
      [list[i], list[j]] = [list[j], list[i]];
    }
  }

  function handleListAdd() {
    let id = list.length;
    list.push({id, name: `${id}-${(Math.random() * 0xffffff).toString(32)}`});
  }
  for (let i = 0; i < 10; i++) {
    list[i] = {id: i, name: `${i}-${(Math.random() * 0xffffff).toString(32)}`};
  }
</script>

<style lang="scss" scoped>
  .list {
    margin: 0 auto;
    width: 500px;
    list-style: none;
    li {
      background-color: rgba(60, 60, 60, 0.8);
      color: white;
      border: 2px solid rgba(0, 0, 0, 0.8);
      margin-top: 4px;
      border-radius: 5px;
      font-size: 20px;
    }
  }

  .list-change-enter-active,
  .list-change-leave-active {
    transition: all 0.8s linear;
  }

  .list-change-move {
    transition: transform 0.8s ease;
  }
  .list-change-enter-from,
  .list-change-leave-to {
    transform: translateX(30px);
  }
</style>
